package org.urchr.beorganized.api.impl.xml;

import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import org.apache.commons.fileupload.FileItem;
import org.urchr.beorganized.api.base.PrivateBaseAPIServlet;
import org.urchr.beorganized.dao.NotesDAO;
import org.urchr.beorganized.dao.UsersDAO;
import org.urchr.beorganized.dao.XMLDocumentBuilder;
import org.urchr.beorganized.dao.errors.GeneralException;
import org.urchr.beorganized.dao.errors.NoPermissionException;
import org.urchr.beorganized.dao.tables.Note;
import org.urchr.beorganized.dao.tables.User;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class Import extends PrivateBaseAPIServlet{

	public Import() {
		skipBody = true;
	}
	
	static Map<String, Object> results = new HashMap<String, Object>();
	
	private Map<String, String> unzippedFiles = new HashMap<String, String>();
	
	private void processNote(Note note, boolean newNote, Element e, User user) throws GeneralException{
		Note parent = note;
		if(newNote){
			note = new Note();
			note.setId(parent.getId());
			note.setUser(user);
		}
		note.setEditUser(user);
		note.setName(e.getAttribute("text"));
		note.setType(NotesDAO.safeInt(e.getAttribute("type"), 0));
		note.setCustomIcon(NotesDAO.safeInt(e.getAttribute("type"), note.getType()));
		note.setContentType(e.getAttribute("contentType"));
		note.setFileName(e.getAttribute("fileName"));
		note.setShareCode(e.getAttribute("shareCode"));
		note.setRecurrence(e.getAttribute("recurrence"));
		note.setCompleted("true".equals(e.getAttribute("completed"))?1:0);
		note.setFileSize(NotesDAO.safeInt(e.getAttribute("fileSize"), 0));
		note.setPriority(NotesDAO.safeInt(e.getAttribute("priority"), 2));
		note.setSort(NotesDAO.safeInt(e.getAttribute("sort"), 0));
		note.setSortType(NotesDAO.safeInt(e.getAttribute("sortType"), 0));
		note.setUrl(e.getAttribute("url"));
		
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
//		Calendar c = Calendar.getInstance();
		try {
			note.setCreateDate(format.parse(e.getAttribute("createDate")));
			//Move dates
		} catch (Exception e2) {}
		try {
			note.setEditDate(format.parse(e.getAttribute("editDate")));
			//Move dates
		} catch (Exception e2) {}
		try {
			note.setStartDate(format.parse(e.getAttribute("startDate")));
			//Move dates
		} catch (Exception e2) {}
		try {
			note.setEndDate(format.parse(e.getAttribute("endDate")));
			//Move dates
		} catch (Exception e2) {}
		
		//Reading file
		try {
			FileInputStream fileInputStream = 
				new FileInputStream(unzippedFiles.get(note.getShareCode()+".bin"));
			ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
			for (int c = fileInputStream.read(); c!=-1; c = fileInputStream.read()) {
				outputStream.write(c);
			}
			fileInputStream.close();
			note.setData(outputStream.toByteArray());
		} catch (Exception e2) {
			// TODO: handle exception
			note.setData(null);
		}
		Note result = NotesDAO.saveNote(servletContext, note, newNote, e.getAttribute("tags"), true, user.getId(), true);
		NodeList nl = e.getChildNodes();
		for (int i = 0; i < nl.getLength(); i++) {
			Node n = nl.item(i);
			if(n instanceof Element){
				Element el = (Element) n;
				processNote(result, true, el, user);
			}
		}
	}
	
	@Override
	protected void doProcessPrivate() throws GeneralException {
		String rnd = getParameter("rnd");
		try {
			if(null==rnd || "".equals(rnd))
				throw new NoPermissionException();
			FileItem item = getFile("file");
			if(item.getSize()<=0)
				throw new NoPermissionException();
			ZipInputStream zipInputStream = new ZipInputStream(item.getInputStream());
			ZipEntry entry = null;
			while((entry = zipInputStream.getNextEntry())!=null){
				File tmpFile = File.createTempFile("beorg", ".tmp");
				BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(tmpFile));
				for (int c = zipInputStream.read(); c!=-1; c = zipInputStream.read()) {
					outputStream.write(c);
				}
				outputStream.close();
				zipInputStream.closeEntry();
				unzippedFiles.put(entry.getName(), tmpFile.getAbsolutePath());
//				System.out.println("Saving "+entry.getName()+" to "+tmpFile.getAbsolutePath());
			}
			if(unzippedFiles.get("contents.xml")==null)
				throw new NoPermissionException();
			XMLDocumentBuilder doc = new XMLDocumentBuilder();
			if(!doc.readXML(unzippedFiles.get("contents.xml")))
				throw new NoPermissionException();
			//archiving all children
			int noteID = NotesDAO.safeInt(getParameter("id"), -1);
			List<Note> children = NotesDAO.getChildrenList(noteID, false);
			for (Note note : children) {
				NotesDAO.archiveNote(userID, note.getId());
			}
			Note note = NotesDAO.getNote(noteID, userID);
			processNote(note, false, doc.getRootElement(), UsersDAO.getUser(userID));
			
			results.put(rnd, new Integer(note.getId()));
			XMLDocumentBuilder out = new XMLDocumentBuilder();
			out.getRootElement("note").setAttribute("id", ""+note.getId());
			sendNode(out.getRootElement());
			
//			throw new NoPermissionException();//Import isn't finished
		} catch (Exception e) {
			e.printStackTrace();
			if(!(e instanceof GeneralException))
				e = new NoPermissionException();
			results.put(rnd, e);
			for (String name : unzippedFiles.keySet()) {
				try {
					File file = new File(unzippedFiles.get(name));
					file.delete();
				} catch (Exception e2) {
				}
			}			
			throw (GeneralException)e;
		}
	}

}
